﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Text;

namespace JdFormsDll
{
    public class MyFormButton : Button
    {
        private Rectangle rect;
        private bool selected = false;
        private bool pressed = false;

        public MyFormButton()
            : base()
        { }

        protected override void OnCreateControl()
        {
            SuspendLayout();
            base.OnCreateControl();
            rect = new Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
            ResumeLayout();
        }

        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            rect = new Rectangle(ClientRectangle.X, ClientRectangle.Y, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
        }

        protected override void OnPaint(PaintEventArgs pevent)
        {
            base.OnPaint(pevent);
            MyForm f = (MyForm)this.FindForm();
            if (f == null) return;
            Graphics gp = pevent.Graphics;
            ButtonRenderer.DrawParentBackground(gp, ClientRectangle, this);
            gp.SmoothingMode = SmoothingMode.HighQuality;

            Color c1 = Color.Empty;
            Color c2 = Color.Empty;

            this.DrawButton(gp, f, out c1, out c2);
            this.DrawText(gp, c1, c2);
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            selected = true;
            Invalidate();
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            selected = false;
            Invalidate();
        }

        protected override void OnMouseUp(MouseEventArgs mevent)
        {
            base.OnMouseUp(mevent);
            pressed = false;
            Invalidate();
        }

        protected override void OnMouseDown(MouseEventArgs mevent)
        {
            base.OnMouseDown(mevent);
            pressed = true;
            Invalidate();
        }

        private void DrawText(Graphics gp, Color c1, Color c2)
        {
            Rectangle r = rect;
            if (pressed) r.Offset(1, 1);

            Color c = c1.BlackAndWhite();
            double d = c1.Diff(c2);
            if (d < 0d) c = c2.BlackAndWhite();

            TextRenderer.DrawText(gp,
                Text,
                Font,
                r,
                c,
                Color.Transparent,
                TextFormatFlags.HorizontalCenter |
                TextFormatFlags.VerticalCenter |
                TextFormatFlags.EndEllipsis);

        }

        private void DrawButton
            (
            Graphics gp,
            MyForm f,
            out Color c1,
            out Color c2
            )
        {
            Color secondcolor = Color.Empty;
            if (f.BackColor.IsEqualTo(f.BackColorShadow, f.ColorsDifferencePercent))
            {
                if (f.BackColor.IsLightColor())
                    secondcolor = f.BackColor.Change(-.25d);
                else
                    secondcolor = f.BackColor.Change(.25d);
            }
            else
            {
                secondcolor = f.BackColorShadow;
            }

            c1 = f.BackColor;
            c2 = secondcolor;

            if (selected)
            {
                c1 = f.BackColor.Change(.1d);
                c2 = secondcolor.Change(.1d);
            }

            if (pressed)
            {
                c1 = secondcolor;
                c2 = f.BackColor;
            }

            using (GraphicsPath gph = JdHelper.RoundRect(rect, 2, 2, 2, 2))
            {
                using (Brush br = new LinearGradientBrush(rect, c1, c2, LinearGradientMode.Vertical))
                    gp.FillPath(br, gph);
                using (Pen p = new Pen(secondcolor, 1))
                {
                    p.Alignment = PenAlignment.Center;
                    p.LineJoin = LineJoin.Round;
                    gp.DrawPath(p, gph);
                }
            }
        }
    }
}
